package com.example.user.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.user.mapper.UserMapper;
import com.example.user.model.User;
import com.example.user.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.example.user.contant.UserContant.USER_LOGIN_STATE;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper , User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    public static boolean verifyPassword(String plainPassword, String hashedPassword) {
        return BCrypt.checkpw(plainPassword, hashedPassword);
    }

    @Override
    public long userRegister(String userAccount, String userPassword, String checkPassword) {

        // 1. 校验
        // 非空校验
        if(StringUtils.isAllBlank(userAccount , userPassword , checkPassword)) return -1;
        // 长度校验
        if(userAccount.length() < 4) return -1;
        if(userPassword.length() < 8 || checkPassword.length() < 8) return -1;
        // 特殊字符校验
        String validPattern = "^[\\x21-\\x7E]+$";
        Matcher matcher = Pattern.compile(validPattern).matcher(userAccount);
        if(!matcher.matches()) return -1;
        // 密码与校验密码一致性
        if(!userPassword.equals(checkPassword)) return -1;
        // 重复校验
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_account" , userAccount);
        long count = this.count(queryWrapper);
        if(count > 0) return -1;


        // 2.加密 BCrypt
        String hashed = BCrypt.hashpw(userPassword, BCrypt.gensalt(12));

        // 3.插入数据
        User user = new User();
        user.setUserAccount(userAccount);
        user.setPassword(hashed);
        boolean saveResult = this.save(user);
        if(!saveResult) return -1;

        return user.getId();
    }

    @Override
    public User userLogin(String userAccount, String userPassword , HttpServletRequest request) {
        // 非空校验
        if(StringUtils.isAllBlank(userAccount , userPassword)) return null;
        // 长度校验
        if(userAccount.length() < 4) return null;
        if(userPassword.length() < 8) return null;
        // 特殊字符校验
        String validPattern = "^[\\x21-\\x7E]+$";
        Matcher matcher = Pattern.compile(validPattern).matcher(userAccount);
        if(!matcher.matches()) return null;

        // 校验密码
        String hashed = BCrypt.hashpw(userPassword, BCrypt.gensalt(12));
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_account" , userAccount);
        // 校验是否存在
        User user = userMapper.selectOne(queryWrapper);

        if(user == null) return null;

        // 判断是否删除
//        if(user.getIsDelete() == 1) return null;

        // 校验密码是否正确
        boolean check = BCrypt.checkpw(userPassword, user.getPassword());
        if(!check) return null;

        // 脱敏
        User safeUser = toSafeUser(user);

        // 记录用户登录态
        request.getSession().setAttribute(USER_LOGIN_STATE , safeUser);

        return safeUser;
    }

    @Override
    public int logout(HttpServletRequest request) {
        request.getSession().removeAttribute(USER_LOGIN_STATE);
        return 1;
    }

    /**
     * 脱敏函数
     * @param user
     * @return
     */
    @Override
    public User toSafeUser(User user){
        User safeUser = new User();
        safeUser.setId(user.getId());
        safeUser.setUserAccount(user.getUserAccount());
        safeUser.setAvatar_url(user.getAvatar_url());
        safeUser.setGender(user.getGender());
        safeUser.setUser_name(user.getUser_name());
        safeUser.setPhone(user.getPhone());
        safeUser.setEmail(user.getEmail());
        safeUser.setCreate_time(user.getCreate_time());
        safeUser.setUser_role(user.getUser_role());
        return safeUser;
    }

}
